/*
 * Copyright (c) 2011-2020, baomidou (jobob@qq.com).
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * <p>
 * https://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.baomidou.mybatisplus.generator.engine;

import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.generator.config.ConstVal;
import com.baomidou.mybatisplus.generator.config.builder.ConfigBuilder;
import com.baomidou.mybatisplus.generator.config.po.TableField;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.google.common.base.Strings;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.app.VelocityEngine;

/**
 * Velocity 模板引擎实现文件输出
 *
 * @author hubin
 * @since 2018-01-10
 */
public class VelocityTemplateEngine extends AbstractTemplateEngine {

  private static final String DOT_VM = ".vm";
  private VelocityEngine velocityEngine;

  @Override
  public VelocityTemplateEngine init(ConfigBuilder configBuilder) {
    super.init(configBuilder);
    if (null == velocityEngine) {
      Properties p = new Properties();
      p.setProperty(ConstVal.VM_LOAD_PATH_KEY, ConstVal.VM_LOAD_PATH_VALUE);
      p.setProperty(Velocity.FILE_RESOURCE_LOADER_PATH, StringPool.EMPTY);
      p.setProperty(Velocity.ENCODING_DEFAULT, ConstVal.UTF8);
      p.setProperty(Velocity.INPUT_ENCODING, ConstVal.UTF8);
      p.setProperty("file.resource.loader.unicode", StringPool.TRUE);
      velocityEngine = new VelocityEngine(p);
    }
    return this;
  }


  @Override
  public void writer(Map<String, Object> objectMap, String templatePath, String outputFile) throws Exception {
    if (outputFile.endsWith(".xml")) {
      TableInfo table = (TableInfo) objectMap.get("table");
      String fieldNames = table.getFieldNames();
      String commonFieldNames = table.getCommonFields().stream().flatMap(
          (Function<TableField, Stream<String>>) tableField -> Stream.of(tableField.getColumnName()))
          .collect(Collectors.joining(", "));
      Path path = Paths.get(outputFile);
      if (path.toFile().exists()) {
        //merge
        List<String> list = Files.readAllLines(path);
        boolean find = false;
        for (int i = 0; i < list.size(); i++) {
          if (list.get(i).contains("<sql id=\"Base_Column_List\">")) {
            find = true;
            continue;
          }
          if (find) {
            find = false;
            if (fieldNames != null) {
              if(Strings.isNullOrEmpty(commonFieldNames)){
                list.set(i, "\t\t\t" + fieldNames);
              }else{
                list.set(i, "\t\t\t" + commonFieldNames + " ," + fieldNames);
              }
            } else {
              list.set(i, "\t\t\t" + commonFieldNames);
            }

          }
        }
        Files.write(path, list);
        logger.debug("更新文件:" + outputFile);
        return;
      }
    }
    Template template = velocityEngine.getTemplate(templatePath, ConstVal.UTF8);
    try (FileOutputStream fos = new FileOutputStream(outputFile);
        OutputStreamWriter ow = new OutputStreamWriter(fos, ConstVal.UTF8);
        BufferedWriter writer = new BufferedWriter(ow)) {
      template.merge(new VelocityContext(objectMap), writer);
    }
    logger.debug("新增文件:" + outputFile);
  }


  @Override
  public String templateFilePath(String filePath) {
    if (null == filePath || filePath.contains(DOT_VM)) {
      return filePath;
    }
    return filePath + DOT_VM;
  }
}
